﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using eWallet.Data.Local;
using eWallet.Data.Local.eWalletDataSetTableAdapters;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using eWallet.Security.Cryptography;
using System.Transactions;
using eWallet.Windows.Controls;

namespace eWallet
{
	/// <summary>
	/// Interaction logic for Window1.xaml
	/// </summary>
	public partial class MainWindow : Window
	{

		private eWalletDataSet DataSet = new eWalletDataSet();

		public MainWindow()
		{
			InitializeComponent();

			this.Height = MainWindowSettings.Default.WindowSize.Height;
			this.Width = MainWindowSettings.Default.WindowSize.Width;
			this.SecretsList.ShowTagCloud = MainWindowSettings.Default.ShowTagCloud;
			this.ViewTagsMenuItem.IsChecked = MainWindowSettings.Default.ShowTagCloud;

			this.PopulateSecretsList();

			this.Title = string.Format("{0} - [{1}]", Assembly.GetExecutingAssembly().GetProductName(), Properties.Settings.Default.DatabasePath);
		}

		protected override void OnClosed(EventArgs e)
		{
			try
			{
				this.DataSet.Dispose();
			}
			catch { }

			base.OnClosed(e);
		}

		protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
		{
			base.OnClosing(e);

			if (!e.Cancel && this.WindowState == WindowState.Normal)
			{
				MainWindowSettings.Default.WindowSize = new Size(this.Width, this.Height);
			}

			MainWindowSettings.Default.Save();
		}



		private void CreateNewSecret()
		{
			SecretWindow wnd = new SecretWindow();

			using (eWalletDataSet ds = new eWalletDataSet())
			{

				var secret = ds.Secrets.NewSecretsRow(Guid.NewGuid());
				secret.GroupId = Guid.Empty;
				wnd.SelectedSecret = secret;

				try
				{
					var result = wnd.ShowDialog();
					if (result.HasValue && result.Value)
					{
						ds.Secrets.AddSecretsRow(wnd.SelectedSecret);
						using (TableAdapterManager tam = new TableAdapterManager(Properties.Settings.Default.DatabasePath))
						{
							try
							{
								tam.BlobsTableAdapter.Update(ds.Blobs);
								tam.SecretsTableAdapter.Update(ds.Secrets);
								tam.SecretsTableAdapter.SetTags(wnd.SelectedSecret.Id, wnd.SelectedTags);

								this.PopulateSecretsList();

								MessageBox.Show(this, "Secret was successfully saved.", "Secret Saved", MessageBoxButton.OK, MessageBoxImage.Information);
							}
							catch (Exception ex)
							{
								throw new ApplicationException("An exception occured while saving the secret.", ex);
							}
						}

					}

				}
				catch (Exception ex)
				{
					ExceptionHandling.DisplayException(ex);
				}
			}
		}

		private void PopulateSecretsList()
		{
			if (null != this.DataSet)
			{
				this.DataSet.Dispose();
			}

			this.DataSet = new eWalletDataSet();

			using (TableAdapterManager tam = new TableAdapterManager(Properties.Settings.Default.DatabasePath))
			{
				tam.GroupsTableAdapter.Fill(this.DataSet.Groups);
				tam.SecretsTableAdapter.Fill(this.DataSet.Secrets);
				tam.TagsTableAdapter.Fill(this.DataSet.Tags);
				tam.SecretsTagsTableAdapter.Fill(this.DataSet.SecretsTags);

				this.SecretsList.DataSource = this.DataSet;
			}
		}

		private void FileExitMenuItem_Click(object sender, RoutedEventArgs e)
		{
			Application.Current.Shutdown();
		}

		private void ToolsOptionsMenuItem_Click(object sender, RoutedEventArgs e)
		{
			OptionsWindow wnd = new OptionsWindow();
			var b = wnd.ShowDialog();
		}

		private void HelpContentsMenuItem_Click(object sender, RoutedEventArgs e)
		{
			FileInfo asmPath = new FileInfo(Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName);
			FileInfo helpPath = new FileInfo(string.Format(@"{0}\help\eWallet-User-Manual.docx", asmPath.Directory.FullName));
			Process.Start(helpPath.FullName);
		}

		private void HelpAboutMenuItem_Click(object sender, RoutedEventArgs e)
		{
			MessageBox.Show("Not implemented...");
		}

		private void FileNewSecretMenuItem_Click(object sender, RoutedEventArgs e)
		{
			this.CreateNewSecret();
		}

		private void FileNewGroupMenuItem_Click(object sender, RoutedEventArgs e)
		{
			GroupWindow wnd = new GroupWindow();

			using (eWalletDataSet ds = new eWalletDataSet())
			{
				wnd.SelectedGroup = ds.Groups.NewGroupsRow(Guid.NewGuid(), string.Empty, EncryptionMethod.Password);

				try
				{
					var result = wnd.ShowDialog();
					if (result.HasValue && result.Value)
					{
						ds.Groups.AddGroupsRow(wnd.SelectedGroup);
						using (TableAdapterManager tam = new TableAdapterManager(Properties.Settings.Default.DatabasePath))
						{
							try
							{
								tam.BlobsTableAdapter.Update(ds.Blobs);
								tam.GroupsTableAdapter.Update(ds.Groups);

								MessageBox.Show(this, "Group was successfully saved.", "Group Saved", MessageBoxButton.OK, MessageBoxImage.Information);
							}
							catch (Exception ex)
							{
								throw new ApplicationException("An exception occured while saving the group.", ex);
							}
						}
					}
				}
				catch (Exception ex)
				{
					ExceptionHandling.DisplayException(ex);
					return;
				}
			}
		}

		private void FileNewDatabaseMenuItem_Click(object sender, RoutedEventArgs e)
		{
			MessageBox.Show("Not implemented...");
		}

		private void ViewTagsMenuItem_Click(object sender, RoutedEventArgs e)
		{
			this.ViewTagsMenuItem.IsChecked = !this.ViewTagsMenuItem.IsChecked;
			this.SecretsList.ShowTagCloud = this.ViewTagsMenuItem.IsChecked;

			MainWindowSettings.Default.ShowTagCloud = this.ViewTagsMenuItem.IsChecked;
			MainWindowSettings.Default.Save();
		}

		private void SecretsList_SecretOpening(object sender, ItemActionEventArgs<eWalletDataSet.SecretsRow> e)
		{
			var module = CryptoModuleFactory.GetCryptoModule(e.Item.GroupsRow);
			if (null != module)
			{
				SecretWindow dlg = new SecretWindow();
				dlg.DecryptionModule = module;
				dlg.SelectedSecret = e.Item;
				dlg.SelectedTabIndex = 1;
				dlg.ShowDialog();
			}
		}

		private void SecretsList_SecretsDeleting(object sender, ItemActionEventArgs<IEnumerable<eWalletDataSet.SecretsRow>> e)
		{
			if (MessageBox.Show(this, "Are you sure you want to delete the selected secrets?", "Delete Secrets", MessageBoxButton.OKCancel, MessageBoxImage.Exclamation) == MessageBoxResult.OK)
			{
				try
				{
					using (TableAdapterManager tam = new TableAdapterManager(Properties.Settings.Default.DatabasePath))
					{
						foreach (var secret in e.Item)
						{
							tam.SecretsTagsTableAdapter.Delete(null, (Guid?)secret.Id);
							tam.SecretsTableAdapter.Delete(secret.Id);
							tam.BlobsTableAdapter.Delete(secret.EncryptedSecretBlobId);
						}
					}

					this.PopulateSecretsList();

					MessageBox.Show(this, "Selected groups successfully deleted.", "Groups Deleted", MessageBoxButton.OK, MessageBoxImage.Information);
				}
				catch (Exception ex)
				{
					ExceptionHandling.DisplayException("An error occured while deleting secret(s).", ex);
				}

				try
				{
					bool deleted = false;
					using (TableAdapterManager tam = new TableAdapterManager(Properties.Settings.Default.DatabasePath))
					{
						var unusedGroups = tam.GroupsTableAdapter.GetUnusedData();
						foreach (var group in unusedGroups)
						{
							if (MessageBox.Show(this, string.Format("The group '{0}' is empty and contains no secrets. Do you want to delete this group?", group.Name), "Delete Group", MessageBoxButton.YesNo, MessageBoxImage.Question) == MessageBoxResult.Yes)
							{
								group.Delete();
								deleted = true;
							}
						}

						tam.GroupsTableAdapter.Update(unusedGroups);
					}

					if (deleted)
					{
						MessageBox.Show(this, "One or more groups were successfully deleted.", "Groups Deleted", MessageBoxButton.OK, MessageBoxImage.Information);
					}
				}
				catch (Exception ex)
				{
					ExceptionHandling.DisplayException("An error occured while deleting group(s).", ex);
				}
			}
		}

		private void SecretsList_GroupOpening(object sender, ItemActionEventArgs<eWalletDataSet.GroupsRow> e)
		{
			GroupWindow dlg = new GroupWindow();
			dlg.SelectedGroup = e.Item;
			dlg.ShowDialog();
		}

		private void SecretsList_NewSecret(object sender, EventArgs e)
		{
			this.CreateNewSecret();
		}

	}
}
